package com.hhd.pdf.components.branch;

import com.hhd.pdf.CommonUtils;
import com.hhd.pdf.components.AbstractInLineBlockComponent;
import com.hhd.pdf.components.functions.PdfFunctionContext;
import com.hhd.pdf.components.functions.PdfFunctionExecutor;
import com.hhd.pdf.context.GeneratorContext;
import com.hhd.pdf.variable.DynamicFormula;
import com.hhd.pdf.variable.VariableContext;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import org.dom4j.Attribute;
import org.dom4j.tree.DefaultElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

@Component
public class IfComponent extends AbstractInLineBlockComponent {

    @Autowired
    @Lazy
    PdfFunctionExecutor pdfFunctionExecutor;

    @Override
    public List<Element> createElements(org.dom4j.Element element,
                                        GeneratorContext context,
                                        VariableContext rootVariableContext) throws DocumentException, IOException {
        if (decide(element, rootVariableContext, context))
            return createPdfElementsByVariableContext(rootVariableContext, element, context);
        return CommonUtils.newList();
    }

    private boolean decide(org.dom4j.Element element,
                           VariableContext rootVariableContext,
                           GeneratorContext context) {
        List<Attribute> attributes = element.attributes();
        HashMap<String, Object> variables = new HashMap<>();
        if (CommonUtils.isEmpty(attributes)) {
            attributes = CommonUtils.newList();
        }
        String function = "";
        for (Attribute attribute : attributes) {
            if ("function".equals(attribute.getName())) {
                function = attribute.getText();
                continue;
            }

            String formulaText = attribute.getText();
            if (CommonUtils.isEmpty(formulaText)) {
                continue;
            }


            Object value = executeFormulaValue(rootVariableContext, formulaText);
            variables.put(attribute.getName(), value);
        }

        return pdfFunctionExecutor.exeute(PdfFunctionContext.builder()
                .function(function)
                .element(element)
                .variableContext(rootVariableContext)
                .generatorContext(context)
                .variables(variables)
                .build(), Boolean.class);
    }

    private Object executeFormulaValue(VariableContext rootVariableContext, String formulaText) {
        if (!formulaText.contains("{{")) {
            return formulaText;
        }

        DynamicFormula<Object> formula = DynamicFormula.formula(formulaText, Object.class);
        rootVariableContext.execute(formula);
        return formula.getFormulaValue();
    }

    @Override
    public void parseComponent(org.dom4j.Element element, GeneratorContext context) throws Exception {
        context.getDocument().addAll(createElements(element, context, context.createRootVariableContext()));
    }

    @Override
    public String getFormula(DefaultElement defaultElement) {
        return defaultElement.asXML();
    }

    @Override
    public Collection<? extends Element> createPdfElement(DefaultElement defaultElement, GeneratorContext context, String parsedFormula) throws DocumentException, IOException {
        return createElements(defaultElement, context, context.createRootVariableContext());
    }

    @Override
    public String getName() {
        return "if";
    }
}
